之前在建站历程十八中写了django如何使用restframework编写自己所用的api,这篇接上篇说一下如何使用jwt进行api的身份验证。
前言
JWT 就是 json web token 的缩写,token的作用很简单,一般用于识别用户身份,避免每次请求都需要验证。我们为什么需要认证呢?看下面这个例子:
将django项目(地址:github)本地运行起来,之前我们都已经实现了api接口,于是输入以下地址(http://127.0.0.1:8000/api/laji/)可以获取到如下的信息:
无需任何认证就可以得到我们想要的信息,如果用python脚本的话,代码如下:
# coding: UTF-8
import re
import requests
def get_url():
url = "http://127.0.0.1:8000/api/laji/"
r = requests.get(url)
r.encoding = 'utf-8'
print(r.text)
get_url()
简单几句就能调用api获取到信息,但是这样会有些问题:
- 所有人无需验证即可调用api,对于我们垃圾服务器来说是一种负担。
- 对于post/put操作所有人都可以添加修改我们的内容,这是不安全的。
于是,我们可以对api做一个验证,避免上述的问题。接下来说下 jwt 在django项目中的配置使用。
一、jwt的下载安装
需要安装两个插件 djangorestframework-jwt 和 django-cors-headers,其中 django-cors-headers 用于解决所谓的跨域问题。
pip install djangorestframework-jwt
pip install django-cors-headers
在全局settings.py install-app 中添加两个插件:
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken', # 设置token
'corsheaders',
...
]
同样在 settings.py 中 middleware 中添加
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 跨域
...
]
同样在 settings.py 中 添加如下配置,表示认证进行jwt认证:
REST_FRAMEWORK = {
.....
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
.....
}
二、添加url路由
在全局路由url.py中添加如下,将 jwt 所需的url添加进去:
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
....
path('api-auth/', obtain_jwt_token),
.......
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
三、修改处理函数
需要在api处理函数(view.py)中添加认证代码,例如我们在所有垃圾查询函数中添加:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication
# 所有垃圾获取处理 继承listAPIView
class RubbishView(ListAPIView):
# 认证后才可以往下进行
permission_classes = (permissions.IsAuthenticated,)
# 进行jwt验证
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
queryset = Rubbish.objects.all()
serializer_class = RubbishSerializer
此时,我们再调用之前的api链接,提示应该如下,因为我们添加了需要认证验证:
四、jwt身份验证
上述操作进行后,我们只有验证后才能调用api了,如何进行验证呢?
其实也很简单,需要将用户名密码post给服务器,获取到服务器返回的token,我们接下来的put/get/post等操作将token填写到头中即可。说起来可能有点抽象,看下面这个例子:
1、获取token
以python为例,只需要向 "http://127.0.0.1:8000/api-auth/" 这个链接 post 我们的用户名密码(这个项目管理员用户名密码是 jerrycoding/jerry123 ), 即可获取到token:
def get_token():
url = "http://127.0.0.1:8000/api-auth/"
params = {"username": "jerrycoding", "password": "jerry123"}
r = requests.post(url, data=params)
r.encoding = 'utf-8'
print(r.text)
2、封装头进行数据获取
这里要注意的是token头的封装,格式要注意!格式应该为“JWT +'token'”,JWT后面有一个空格,空格后就是获取到的token值。一个完整的例子代码如下:
# coding: UTF-8
import requests
def get_token():
url = "http://127.0.0.1:8000/api-auth/"
params = {"username": "jerrycoding", "password": "jerry123"}
r = requests.post(url, data=params)
r.encoding = 'utf-8'
return r.json()["token"]
def get_url():
# 获取token
token = get_token()
# 造头 注意格式
headers = {'Authorization': 'JWT '+token}
url = "http://127.0.0.1:8000/api/laji/"
r = requests.get(url, headers=headers)
r.encoding = 'utf-8'
print(r.text)
get_url()
此时,运行代码我们又能获取数据了,而且数据获取是需要认证才可以的。
以上就是如何简单的为 api 添加身份验证,上述只是允许登陆用户调用api,比如你有时候只要管理员来调用api或者指定某个用户调用api,直接改处理函数中的认证方式就可以,大家自己可以再深入研究下。最后,本期修改代码已经上传工程代码目录 github。
《django 建站历程系列文章》